<?php

require_once 'lib/JWT.php';

// Préparation d'un jeton de sécurité
function prepareToken() {
    // On crée le header
    $header = [
        'typ' => 'JWT',
        'alg' => 'HS512'
    ];

    // On crée le contenu (payload)
    $payload = [
        'user_id' => $_SESSION['noutilisateur'],
//        'roles' => [
//            'ROLE_ADMIN',
//            'ROLE_USER'
//        ],
        'courriel' => $_SESSION['adressecourriel']
    ];

    $jwt = new JWT();

    $jeton = $jwt->generate($header, $payload, $_ENV["SECRET"]);

    return sprintf("Bearer %s", $jeton);
}

/**
 * Pour l'ouverture de chaque page, vérifie si la constante est définie et égale.
 */
function isValidConstant() {
    if (!defined("LIBERATIONSWEB")) {
        return -1;
    }
    if (isset($_SESSION['HTTP_USER_AGENT']) &&
            $_SESSION['HTTP_USER_AGENT'] != md5(filter_input(INPUT_SERVER, 'HTTP_USER_AGENT'))) {
        return -1;
    }
    return 1;
}

/**
 * Vérifie le facteur 2FA/MFA a été créé dans la bd pour l'utilisateur courant
 */
function isSet2FA() {
    return (!empty($_SESSION["2fa_set"]) && $_SESSION["2fa_set"]);
}

/**
 * Check the validity of a JWT token.
 * @return boolean
 */
function isValidToken() {
    $jeton = filter_input(INPUT_POST, 'jeton');
    if (empty($jeton)) {
        $jeton = filter_input(INPUT_GET, 'jeton');
    }

    // On vérifie si la chaine commence par "Bearer "
    $matches = array();
    if (!isset($jeton) || !preg_match('/Bearer\s(\S+)/', $jeton, $matches)) {
        return false;
    }

    // On extrait le token
    $jeton2 = str_replace('Bearer ', '', $jeton);
    $jwt = new JWT();

    if (
    // On vérifie la validité
            !$jwt->isValid($jeton2) ||
            // On vérifie la signature
            !$jwt->check($jeton2, $_ENV["SECRET"]) ||
            // On vérifie l'expiration
            $jwt->isExpired($jeton2)
    ) {
        return false;
    }

    return true;
}

/**
 * Est-ce que la session est fermée ou encore valide??
 */
function isValidSession() {
    if (isValidConstant() == -1) {
        $code = -1; //La constante de départ manquante
    } elseif (!isset($_SESSION['utilisateur']) || $_SESSION['utilisateur'] == -1) {
        $code = -2; //Pas de session utilisateur
    } elseif (getMicroTime() - 3600 > $_SESSION['temps']) {
        $code = -3; //Délai d'inactivité dépassé
    } elseif (!isSet2FA()) { //Facteur 2FA créé ?
        $code = -4;
    } elseif (!isValidToken()) {
        $code = -6; //Pas de jeton de sécurité ou jeton invalide
    } elseif ($GLOBALS["IP"] !== getenv("REMOTE_ADDR")) {
        $code = -11; //Adresse Ip différente de celle d'origine
    } elseif (count(checkAccessAlreadyInUse()) > 0) {
        $code = -9; // Accès ne doit pas être déjà utilisé.
    } else {
        $code = 1; // Ok, tout est valide
    }
    return $code;
}

/**
 * 
 * @return type
 */
function checkAccessAlreadyInUse() {
    $sqlparam["connexion"] = "maitre";
    $sqlparam["table"][] = "administration";
    $sqlparam["where"][] = "refutilisateur = '" . $_SESSION["noutilisateur"] . "'";
    $sqlparam["where"][] = "acces=1";
    return executerRequeteSql($sqlparam);
}

/**
 * 
 */
function buildHeader() {
    header("Content-type: text/html; charset=utf-8");
    header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");               // Date in the past
    header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");  // always modified
    //TODO vérification si cela bloque les requêtes AJAX nécessaires dans l'application (max-age=0).
    header("Cache-Control: no-store, no-cache, must-revalidate"); //, max-age=0");   // HTTP/1.1
    header("Cache-Control: post-check=0, pre-check=0", false);
    header("Pragma: no-cache");
}

/**
 * Préparation d'une nouvelle header d'une session
 */
function prepareSession() {
    buildHeader();

    //Entête de la page
    $output = "<!DOCTYPE HTML PUBLIC \" - //W3C//DTD HTML 4.01 Transitional//EN\" ";
    $output .= "\"http://www.w3.org/TR/html4/loose.dtd\">\n ";
    $output .= "<HTML>\n";
    $output .= "   <HEAD>\n";
    $output .= "      <TITLE>" . $GLOBALS["APPLICATION"] . "</TITLE>\n";
    $output .= "      <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n";
    $output .= "      <link type=\"text/css\" href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css' rel='stylesheet'>";
    $output .= "      <link type=\"text/css\" href=\"css/jquery-ui.css\" rel=\"stylesheet\" />\n";
    $output .= "      <script type=\"text/javascript\" src=\"js/jquery.js\"></script>\n";
    $output .= "      <script type=\"text/javascript\" src=\"js/jquery-ui.js\"></script>\n";
    $output .= "      <link type=\"text/css\" href=\"css/style_std.css\" rel=\"stylesheet\" />\n";
    $output .= "      <link type=\"text/css\" href=\"css/style_alert.css\" rel=\"stylesheet\" />\n";

    $output .= "      <script src=\"js/notifIt.min.js\" type=\"text/javascript\"></script>\n";
    $output .= "      <link href=\"css/notifIt.min.css\" type=\"text/css\" rel=\"stylesheet\">\n";
    $output .= "      <script type=\"text/javascript\" src=\"js/plugin_maskedinput.js\"> </script>\n";
    $output .= "      <script src=\"js/plugin_validate.js\"></script>\n";
    $output .= "      <script src=\"js/plugin_datepicker.js\"></script>\n";
    $output .= "      <script src=\"js/fonctions.js\"></script>\n";
    $output .= "      <script src=\"js/validations.js\"></script>\n";
    $output .= "      <script src=\"js/jalert.js\"></script>\n";
    $output .= "      <script src=\"js/horloge.js\"></script>\n";
    return $output;
}

/**
 * 
 * @param type $msg
 */
function retireVariableSession($msg = '') {
    $_SESSION = array();

    $params = session_get_cookie_params();
    setcookie(session_name(), "", time() - 42000,
            $params["path"],
            $params["domain"],
            $params["secure"],
            $params["httponly"]
    );

    if (!empty($msg)) {
        session_destroy();
        header("Location:index.php?msg=$msg", true, 303);
        exit;
    } else {
        header("Location:index.php");
    }
}

/**
 * Ferme la session en cours, dont le script a été ouvert dans une nouvelle fenêtre
 * autre que la fenêtre principale (pop-up).
 */
function fermeSessionForm() {
    if (filter_input(INPUT_COOKIE, session_name(), FILTER_SANITIZE_STRING) !== "") {
        setcookie(session_name(), "", time() - 3600, "/");
        setcookie(session_name(), false);
    }

    $_SESSION = array();
    session_destroy();
    print prepareSession();
    $message = "<center>Une erreur s'est produite ou le temps est écoulé.<br><br>";
    $message .= "Vous devez être authentifié pour accéder à ce site.";
    $message .= "<br><br><input type='button' onclick='javascript:window.close();' value='Fermer la fenêtre'></center>";
    die($message);
}

/**
 * Filtrer toutes les valeurs saisies en POST/GET
 */
function filterInputValue() {

    // Vérifier POST en premier
    if (filter_input_array(INPUT_POST)) {
        foreach (filter_input_array(INPUT_POST) as $clef => $valeur) {
            if (!is_array($valeur)) {
                $GLOBALS[$clef] = antiInjection($valeur);
            } else {
                $GLOBALS[$clef] = $valeur;
            }
        }
    }
    if (filter_input_array(INPUT_GET)) {
        foreach (filter_input_array(INPUT_GET) as $clef => $valeur) {
            if (!isset($GLOBALS[$clef])) {
                $GLOBALS[$clef] = antiInjection($valeur);
            }
        }
    }
}

/**
 * Ferme la session en cours
 * 
 * @param type $msg
 */
function fermeSessionUtilisateur($msg = '') {

    if (isset($_SESSION["utilisateur"]) && isset($_SESSION["adressecourriel"])) {
        $sqlparam["connexion"] = "maitre";
        $sqlparam["type"] = "UPDATE";
        $sqlparam["table"][] = "administration";
        $sqlparam["where"][] = sprintf("utilisateur = '%s'", addslashes($_SESSION["utilisateur"]));
        $sqlparam["where"][] = sprintf("email = '%s'", addslashes($_SESSION["adressecourriel"]));
        $sqlparam["champs"]["essais"] = 0;
        executerRequeteSql($sqlparam);
    }

    retireVariableSession($msg);
}

/**
 * Vérifie si le profil satisfait aux conditions d'utilisation
 * Token 2fa activé
 * Mot de passe temporaire remplacé par un nouveau mot de passe
 */
function checkProfil($page) {
    $page2 = $page;
    $sqlparam["connexion"] = "maitre";
    $sqlparam["table"][] = "administration";
    $sqlparam["champs"][] = "refutilisateur";
    $sqlparam["champs"][] = "temporaire";
    $sqlparam["champs"][] = "secret2fa";
    $sqlparam["where"][] = "(temporaire = 1 OR secret2fa IS null)";
    $sqlparam["where"][] = "refutilisateur =" . $_SESSION["noutilisateur"];

    $result = executerRequeteSql($sqlparam);

    //Si l'un de ces 2 éléments est vide, retourne à la page profil
    if (!empty($result) && ($result[0]["temporaire"] == 1 || $result[0]["secret2fa"] == null)) {
        $page2 = "profil";
    }

    return $page2;
}
